<template>
  <div ref="resizeBox" :style="getCardStyle" class="card-view-box rel">
    <draggable
      v-model="cardConfigsData.options"
      v-bind="{ group: 'groupName', animation: 200, handle: '.draggable-move', disabled: !isConfiguring }">
      <transition-group
        :class="{'show-item-border': isConfiguring}"
        type="transition"
        class="draggable-item-list">
        <template v-for="(item, index) in cardConfigsData.options" >
          <div
            v-if="item.emptyVisible || !isEmptyFile(item)"
            :key="item.key + index"
            :style="itemStyle(item)"
            :class="{'active-item': item.key === activeKey, 'draggable-item-hover': isConfiguring, height24: item.showTitle && item.titleWrap}"
            class="draggable-item"
            @click="onFieldClick(item.key)"
          >
            <el-tooltip :disabled="item.showType !== 'tag'" :open-delay="500" placement="top">
              <div slot="content">
                <div class="ellipsisOne">{{ item.subformFullName || item.name || '--' }}：{{ getFieldValue(item) }}</div>
              </div>
              <div
                :class="{'one-row': !item.titleWrap, 'draggable-move': isConfiguring, 'height-full': item.dividerDirection === 1}"
                :style="colStyle(item)"
                class="draggable">
                <div :class="{'one-row': !item.titleWrap, 'height-full': item.dividerDirection === 1}" :style="insideColStyle(item)">
                  <div
                    v-if="item.showTitle"
                    :style="titleStyle(item)"
                    :title="item.subformFullName || item.name"
                    class="label ellipsisOne">
                    <div class="ellipsisOne">{{ item.subformFullName || item.name || '--' }}:</div>
                  </div>
                  <!-- 富文本 -->
                  <div v-if="item.type === 'richEditor'" class="value richeditor-readonly richeditor" style="flex-wrap: wrap;" v-html="setHtmlContent(item[valueKey])" />
                  <!-- 头像 -->
                  <div v-else-if="item.key === 'creatorAvatar'" class="avatar" @click.stop="()=>{}">
                    <img v-if="isConfiguring" :src="defaultAvatarImg" :width="item.avatarSize || 42" :height="item.avatarSize || 42" alt="头像">
                    <AuditorAvatar v-else :user-list="computedUserList" :slice-num="3" :avatar-size="item.avatarSize || 42" hidden-name />
                  </div>
                  <!-- 附件 -->
                  <div v-else-if="item.type === 'upAttachment' && item[valueKey] && item[valueKey].length" class="file-box">
                    <CardThumbnailFiles :file-list="item[valueKey]" @showStatusToggle="showStatusToggle"/>
                  </div>
                  <!-- 标签 -->
                  <div
                    v-else-if="item.showType === 'tag'"
                    :style="getFontStyle(item)"
                    :title="item[valueKey]"
                    :class="{'ellipsis-text': !fontLengthFirst, 'text-padding': item.showType !== 'tag'}"
                    class="value tag-value">
                    <div v-if="fontLengthFirst">{{ getFieldValue(item) }}</div>
                    <div v-else class="ellipsisOne" style="width: 100%">{{ getFieldValue(item) }}</div>
                  </div>
                  <LinkElement
                    v-else-if="item.type === 'link'"
                    :is-table="false"
                    :show-icons="true"
                    :element="listData.content ? getListValue(item) : { options: null }"
                    :auto-pick="listData.content ? getListValue(item) && getListValue(item).autoPick : false"
                    :link="listData.content ? getListValue(item) && getListValue(item).url : getFieldValue(item)"
                    :link-name="listData.content && getListValue(item) && getListValue(item).defaultLinkName ? getListValue(item).defaultLinkName : '查看网页'" />
                  <!-- 分割线 -->
                  <div
                    v-else-if="item.key.startsWith('divider')"
                    class="value divider-box">
                    <div :style="getDividerStyle(item)" />
                  </div>
                  <!-- 默认 -->
                  <div
                    v-else
                    :style="getFontStyle(item)"
                    :title="item[valueKey]"
                    :class="{'ellipsis-text': !fontLengthFirst}"
                    class="value">
                    <div v-if="fontLengthFirst">{{ ['select', 'checkbox', 'radio'].includes(item.type) ? getSelectFieldValue(item) : getFieldValue(item) }}</div>
                    <div v-else class="ellipsisOne" style="width: 100%">{{ ['select', 'checkbox', 'radio'].includes(item.type) ? getSelectFieldValue(item) : getFieldValue(item) }}</div>
                  </div>
                </div>
              </div>
            </el-tooltip>
            <img v-if="isConfiguring" :src="draggableImg" class="draggable-img draggable-move" alt="" >
          </div>
        </template>
      </transition-group>
    </draggable>
    <slot name="btn"/>
  </div>
</template>

<script>
import { mapState } from 'vuex';
import draggable from 'vuedraggable';
import LinkElement from '@/views/legal/process/components/formMake/components/linkElement';
import AuditorAvatar from '@/components/Common/auditProcess/module/auditorAvatar';
import CardThumbnailFiles from '@/components/Common/cardThumbnailFiles';
import draggableImg from '@/assets/orderlist/draggable.png';
import defaultAvatarImg from '@/assets/user-avatar.png';
export default {
  components: {
    draggable,
    CardThumbnailFiles,
    LinkElement,
    AuditorAvatar
  },
  model: {
    prop: 'cardConfigsData',
    event: 'change'
  },
  props: {
    cardConfigsData: {
      type: Object,
      default: () => ({
        width: '400',
        minWidth: '',
        maxWidth: '',
        height: '',
        minHeight: '',
        maxHeight: '',
        options: [],
        isEnable: false
      })
    },
    activeKey: {
      type: String,
      default: ''
    },
    valueKey: { // 自定义表单：defaultValue, 列表: value
      type: String,
      default: 'value'
    },
    isConfiguring: { // 自定义表单配置中
      type: Boolean,
      default: false
    },
    userList: {
      type: Array,
      default: () => []
    },
    listData: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      draggableImg,
      defaultAvatarImg,
      fontLengthFirst: true // 字符长度优先模式，文字超出优先换行还是显示...
    };
  },
  computed: {
    ...mapState({
      'userInfo': state => state.user.userInfo
    }),
    computedUserList() {
      return this.userList.length ? this.userList : [{ avatar: this.userInfo.avatar, id: this.userInfo.id }];
    },
    getCardStyle() {
      const styleProps = ['width', 'minWidth', 'maxWidth', 'height', 'minHeight', 'maxHeight'];
      const styleData = {};
      styleProps.forEach(prop => {
        const propVal = this.cardConfigsData[prop];
        if (propVal && !isNaN(Number(propVal)) && !propVal.includes('%')) {
          styleData[prop] = propVal + 'px';
        } else {
          styleData[prop] = propVal;
        }
      });
      return styleData;
    }
  },
  mounted() {
    this.$nextTick(() => {
      const resizeObserver = new ResizeObserver(entries => {
        let resizing = true;
        setTimeout(() => {
          if (resizing) {
            this.$emit('freshView');
            resizing = false;
          }
        }, 2000);
      });
      resizeObserver.observe(this.$refs.resizeBox);
    });
  },
  methods: {
    getListValue(item) {
      return this.listData.content[item.key];
    },
    colStyle(item) {
      let { padding } = item;
      if (!padding) padding = { top: 0, bottom: 0, left: 0, right: 0 };
      return {
        paddingTop: padding.top + 'px',
        paddingBottom: padding.bottom + 'px',
        paddingLeft: padding.left + 'px',
        paddingRight: padding.right + 'px',
        fontSize: item.key === 'creatorAvatar' ? 0 : ''
      };
    },
    titleStyle(item) {
      return {
        maxWidth: item.titleWrap ? '100%' : 'min(6em, 100%)',
        fontSize: item.fontSize + 'px',
        color: item.fontColor,
        alignItems: item.verticalAlign,
        padding: item.type === 'richEditor' ? '0 6px' : '',
        minHeight: item.showType === 'tag' ? '20px' : '32px',
        fontWeight: item.titleStyle && item.titleStyle.includes('bold') ? 'bold' : '',
        fontStyle: item.titleStyle && item.titleStyle.includes('italic') ? 'italic' : '',
        textDecoration: item.titleStyle && item.titleStyle.includes('underline') ? 'underline' : ''
      };
    },
    getDividerStyle(item) {
      const styles = {};
      const { dividerWidth, dividerStyle, dividerColor } = item;
      const lineStyle = `${dividerWidth}px ${dividerStyle} ${dividerColor}`;
      if (item.dividerDirection === 0) { // 横向
        styles.borderTop = lineStyle;
        styles.width = '100%';
      } else if (item.dividerDirection === 1) { // 纵向
        styles.borderRight = lineStyle;
        styles.height = '100%';
      }
      return styles;
    },
    getFontStyle(item) {
      const baseStyle = {
        fontSize: item.fontSize + 'px',
        color: item.fontColor,
        alignItems: item.verticalAlign
      };
      return baseStyle;
    },
    itemStyle(item) {
      let { margin, padding } = item;
      if (!margin) margin = { top: 0, bottom: 0 };
      if (!padding) padding = { top: 0, bottom: 0, left: 0, right: 0 };
      const configs = {
        width: this.getFieldWidth(item.gridType),
        marginTop: margin.top + 'px',
        marginBottom: margin.bottom + 'px'
      };
      const { borderStyle, borderVisible } = item;
      if (!this.isConfiguring && borderStyle && Array.isArray(borderVisible) && borderVisible.length) {
        borderVisible.forEach(i => {
          configs[`border-${i}`] = `1px ${borderStyle} #dcdfe6`;
        });
      }
      return configs;
    },
    insideColStyle(item) {
      const baseConfig = {
        width: '100%',
        justifyContent: item.textAlign || 'center',
        alignItems: item.verticalAlign || 'center'
      };
      if (item.showType !== 'tag') return baseConfig;
      let { radius } = item;
      if (typeof radius !== 'object') radius = { topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0 };
      return {
        ...baseConfig,
        borderTopLeftRadius: radius.topLeft + 'px',
        borderTopRightRadius: radius.topRight + 'px',
        borderBottomLeftRadius: radius.bottomLeft + 'px',
        borderBottomRightRadius: radius.bottomRight + 'px',
        backgroundColor: item.tagColor
      };
    },
    getFieldWidth(val) {
      // 旧数据
      if (typeof val === 'string' || isNaN(Number(val))) {
        return '33.33%';
      }
      return (Number(val) / 24 * 100) + '%';
    },
    isEmptyFile(item) {
      // 下拉筛选当选项隐藏设置中含有“无选项”时，字段值为空也需要显示字段
      if (this.isConfiguring || item.key === 'creatorAvatar' || item.key.startsWith('divider') || (['select', 'checkbox', 'radio'].includes(item.type) && (item.optionsHide || []).includes('无选项'))) return false;
      if (item.type === 'link') {
        return !(this.listData.content ? this.getListValue(item) && this.getListValue(item).url : item[this.valueKey]);
      }
      const value = item[this.valueKey];
      return (!value && value !== 0) || (Array.isArray(value) && !value.length) || (item.type === 'richEditor' && value === '<p><br></p>');
    },
    setHtmlContent(val) {
      return (val === '<p><br></p>' || !val) ? '--' : val;
    },
    getFieldValue(data, ellipsisOne = true) {
      if (!data[this.valueKey]) return '--';
      if (data[this.valueKey].length <= data.fontLength || !ellipsisOne) return data[this.valueKey];
      return String(data[this.valueKey]).substring(0, data.fontLength) + '...';
    },
    // 选项值需要过滤卡片配置中“选项隐藏”设置选中的字段
    getSelectFieldValue(data, ellipsisOne = true) {
      if (!data[this.valueKey]) return '--';
      // 选项隐藏设置移除“无选项”字段，避免需要过滤的字段值也存在“无选项”同名字段
      const hideOptions = (data.optionsHide || []).filter(i => i !== '无选项');
      const showVal = data[this.valueKey].split(',').filter(val => !hideOptions.includes(val)).join();
      if (showVal.length <= data.fontLength || !ellipsisOne) return showVal || '--';
      return String(showVal).substring(0, data.fontLength) + '...';
    },
    onFieldClick(key) {
      this.$emit('onFieldClick', key);
    },
    showStatusToggle() {
      this.$emit('freshView');
    }
  }
};
</script>

<style scoped lang="scss">
.card-view-box {
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 0 10px 0 rgb(221 225 234 / 80%);
  @include scrollBar($x: hidden, $y: auto, $width: 6px);
  .draggable-item-list {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
    .draggable-item {
      position: relative;
      display: flex;
      align-items: center;
      background-color: #fff;
      overflow: hidden;
      .check {
        margin-right: 8px;
      }
      .draggable {
        flex: 1;
        font-size:14px;
        font-family:PingFangSC-Regular,PingFang SC;
        color:rgba(20,28,61,1);
        line-height:1.2;
        //max-width: calc(100% - 4px);
      }
      .draggable-img {
        width: 16px;
        height: 16px;
        visibility: hidden;
        position: absolute;
        right: 6px;
      }
      .draggable-move {
        display: flex;
        align-items: center;
        cursor: move;
      }
      .draggable-tag {
        color: #FF4E5F;
        font-size: 12px;
        margin-left: 3px;
      }
      .one-row {
        display: flex;
        overflow: hidden;
        align-items: center;
      }
      .label {
        display: flex;
        align-items: center;
        flex-shrink: 0;
        margin-right: 8px;
        min-height: 32px;
        align-self: flex-start;
      }
      .value {
        min-height: 32px;
        //white-space: pre-line;;
        word-break: break-all;
        line-height: 1.2;
        display: flex;
        align-items: center;
      }
      .tag-value {
        //margin: 0 auto;
        min-height: 20px;
        > div {
          text-align: center;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }
      }
      .ellipsis-text {
        flex: 1;
        overflow: hidden;
      }
      .file-box {
        width: 100%;
        min-height: 32px;
        padding-left: 6px;
        ::v-deep {
          .card-file-container {
            margin-top: 0;
          }
        }
      }
      .divider-box {
        width: 100%;
        height: 100%;
        justify-content: center;
      }
      &::v-deep {
        .link-name {
          max-width: 300px;
        }
      }
    }
    .draggable-item-hover {
      &:hover {
        background-color: #FAFAFA;
        .draggable-img {
          visibility: visible;
        }
      }
    }
    .user-avatar-box {
      ::v-deep {
        img {
          cursor: pointer !important;
        }
      }
    }
    .height24 {
      .label, .value {
        // min-height: 24px !important;
        padding: 0;
      }
    }
  }
  .height-full {
    height: 100%;
  }
  .show-item-border {
    .draggable-item {
      border: 1px solid #EBEEFD;
    }
    .active-item {
      border: 1px solid #406eff;
    }
  }
  .richeditor {
    padding: 6px !important;
    border: 1px dashed #EBEEFD !important;
    border-radius: 4px;
  }
}
</style>
<style lang="scss">
.richeditor-readonly {
  width: calc(100% - 6px) !important;
  div, span, applet, object, iframe,
  h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  a, abbr, acronym, address, big, cite, code,
  del, dfn, em, img, ins, kbd, q, s, samp,
  small, strike, strong, sub, sup, tt, var,
  b, u, i, center,
  dl, dt, dd, ol, ul, li,
  fieldset, label, legend,
  table, caption, tbody, tfoot, thead, tr, th, td,
  article, aside, canvas, details, embed,
  figure, figcaption, footer, header, hgroup,
  menu, nav, output, ruby, section, summary,
  time, mark, audio, video {
    margin: 0! important;
    padding: 0! important;
    font-size: 12px;
    max-width: 100%;
  }
  .tb-table {
    border-collapse: collapse;
    border-spacing: 0;
    td, th {
      border: 1px solid #aaa;
    }
  }
}
</style>
